package com.moli.iov.util;

import com.moli.iov.exception.BusinessException;
import com.moli.iov.rest.RestResponse;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.hibernate.validator.HibernateValidator;

/**
 * The type Validation util. 校验参数工具类
 *
 * @author whl
 * @date 2019-09-13 00:05:14
 */
public class ValidationUtils {

  /**
   * 开启快速结束模式 failFast (true)
   */
  private static Validator validator = javax.validation.Validation
      .byProvider(HibernateValidator.class).configure()
      .failFast(true).buildValidatorFactory().getValidator();


  public static void validateBean(Object t, Class<?>... groups) {
    {
      Set<String> setErr = new HashSet<>();
      if (t == null) {
        throw new BusinessException("实体类不能为空");
      }
      Set<ConstraintViolation<Object>> validate = validator.validate(t, groups);
      boolean hasError = validate != null && validate.size() > 0;
      if (hasError) {
        for (ConstraintViolation violation : validate) {
          StringBuffer buffer = new StringBuffer();
          //属性名称
          buffer.append(violation.getPropertyPath().toString());
          //message
          buffer.append(violation.getMessage());
          setErr.add(buffer.toString());
        }
        throw new BusinessException(setErr.toString());
      }
    }
  }

  /**
   * 校验bean的某一个属性
   *
   * @param t bean
   * @param propertyName 属性名称
   * @return ValidResult
   */
  public static void validateProperty(Object t, String propertyName) {
    Set<String> setErr = new HashSet<>();
    if (t == null) {
      throw new BusinessException("实体类不能为空");
    }
    Set<ConstraintViolation<Object>> constraintViolations = validator
        .validateProperty(t, propertyName);
    boolean hasError = constraintViolations != null && constraintViolations.size() > 0;
    if (hasError) {
      for (ConstraintViolation violation : constraintViolations) {
        StringBuffer buffer = new StringBuffer();
        //属性名称
        buffer.append(propertyName);
        //message
        buffer.append(propertyName + violation.getMessage());
        setErr.add(buffer.toString());
      }
      throw new BusinessException(setErr.toString());
    }
  }

  public static <T> RestResponse<Set> restResponseValidateBean(T t, Class<?>... groups) {
    Set<String> setErr = new HashSet<>();
    if (t == null) {
      return RestResponse.failure("实体类不能为空");
    }
    Set<ConstraintViolation<T>> violationSet = validator.validate(t, groups);
    boolean hasError = violationSet != null && violationSet.size() > 0;
    if (hasError) {
      for (ConstraintViolation<T> violation : violationSet) {
        StringBuffer buffer = new StringBuffer();
        //属性名称
        buffer.append(violation.getPropertyPath().toString());
        //message
        buffer.append(violation.getMessage());
        setErr.add(buffer.toString());
      }
      System.out.println(setErr.toString());
      return RestResponse.failure(setErr);
    } else {
      return RestResponse.success();
    }

  }

  public static <T> RestResponse<Set<String>> restResponseValidateProperty(T obj,
      String propertyName) {
    Set<String> setErr = new HashSet<>();
    if (obj == null) {
      return RestResponse.failure("实体类不能为空");
    }
    Set<ConstraintViolation<T>> violationSet = validator.validateProperty(obj, propertyName);
    boolean hasError = violationSet != null && violationSet.size() > 0;
    if (hasError) {
      for (ConstraintViolation<T> violation : violationSet) {
        StringBuffer buffer = new StringBuffer();
        //属性名称
        buffer.append(propertyName);
        //message
        buffer.append(propertyName + violation.getMessage());
        setErr.add(buffer.toString());
      }
      return RestResponse.failure(setErr);
    } else {
      return RestResponse.success();
    }
  }

  /**
   * 返回一个校验失败信息
   * @param t
   * @param groups
   * @return
   */
  public static void restResponseValidate(Object t, Class<?>... groups) {
    String msg = "参数不能为空";
    if (t == null) {
      throw new BusinessException(msg);
    }
    Set<ConstraintViolation<Object>> violationSet = validator.validate(t, groups);
    boolean hasError = violationSet != null && violationSet.size() > 0;
    if (hasError) {

      Iterator<ConstraintViolation<Object>> iterator = violationSet.iterator();
      if(iterator.hasNext()){
        ConstraintViolation<Object> next = iterator.next();
        msg = next.getMessage();
      }

      throw new BusinessException(msg);
    }

  }
}
